//
//  HomeTabContr.swift
//  新浪微博
//
//  Created by waterfoxjie on 15/7/30.
//  Copyright © 2015年 zj. All rights reserved.
//

import UIKit

class HomeTabContr: BaseTabContr , StatusCellDelegate{
    
    // MARK: - 定义一个微博数据数组
    var statuses : [XLStatuses]? {
    
        didSet {
    
            // 刷新数据
            tableView.reloadData()
        }
    }
    
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        // 判断是否登录，没有才显示下面的信息
        if !UserAccount.userLogin {
        
            norLoginView?.setupViewInfo(true, imgName: "visitordiscover_feed_image_smallicon", message: "关注一些人，回这里看看有什么惊喜")
            
            return
        }
        
        // 注册通知
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "StatusPict:", name: StatusPictCellNotification, object: nil)
        
        prepareTableView()
        
        loadData()
        
    }
    
    // 释放通知
    deinit {
        
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    // MARK: - 选中照片的方法
    @objc private func StatusPict(n : NSNotification) {
        
        // 获取参数：注意从自定义通知中获取参数，要检查参数是否有值
        guard let urls = n.userInfo![StatusPictCellURLKey] as? [NSURL] else {
        
            print("url不存在")
            
            return
        }
        
        guard let indexPath = n.userInfo![StatusPictCellindexPathKey] as? NSIndexPath else {
        
            print("index没有值")
            
            return
        }
        
        // 检查图像视图
        guard let pictView = n.object as? StatusPictureView else {
        
            print("图像视图不存在...")
            
            return
        }
        
        // 记录属性
        self.pictView = pictView
        
        presentIndex = indexPath
        
        // 设置图像
        presentIconView.sd_setImageWithURL(urls[indexPath.item])
        
        // 添加控制器
        let vc = PhotoBrowserViewContr(urls: urls, index: indexPath.item)
        
        // 自定义转场（设置了之后，前面的视图被覆盖到后面），以下两个操作缺一不可
        // 指定代理
        vc.transitioningDelegate = self
        
        // 指定Modal的转场模式(设置为自定义)
        vc.modalPresentationStyle = UIModalPresentationStyle.Custom
        
        presentViewController(vc, animated: true, completion: nil)
        
    }
    
    // MARK: - 准备表格视图
    private func prepareTableView() {
    
        // 注册原型cel
        // rawValue ：返回枚举对应的实际数值
        tableView.registerClass(StatusNormalCell.self, forCellReuseIdentifier: StatusCellID.StatusNormalCell.rawValue)
        
        tableView.registerClass(StatusForwardCell.self, forCellReuseIdentifier: StatusCellID.StatusForwardCell.rawValue)
        
        // 设置预估行高以及行高自动布局
        tableView.estimatedRowHeight = 300
        
        // 去调下划线
        tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        
        // 下拉刷新（高度：60）
        refreshControl = XLRefreshContr()
        
        // 添加监听方法
        refreshControl?.addTarget(self, action: "loadData", forControlEvents: UIControlEvents.ValueChanged)
        
    }
    
    
    // MARK: - 加载微博数据
    // 设置一个上拉刷新标记
    private var pullupRefreshFlag = false
    
    func loadData() {
        
        // 开始动画，这里只是开启了刷新控件的动画，并不会触发加载数据的方法
        refreshControl?.beginRefreshing()
        
        // 获取到数组中第一条记录的id
        // 第一次执行此方法的时候，模型数组为nil
        var since_id = statuses?.first?.id ?? 0
        
        var max_id = 0
        
        // 判断是否是上拉刷新
        if pullupRefreshFlag {
            
            since_id = 0
        
            // 上拉刷新要获取到数组的最后一条数据
            max_id = statuses?.last?.id  ?? 0
            
        }
        
        XLStatuses.loadStatus(since_id , max_id : max_id) {(statusList, error) -> () in
            
            // 刷新结束之后，关闭刷新控件，结束刷新动画
            self.refreshControl?.endRefreshing()
            
            // 复位上拉属性值，保证下一次任然能够上拉，以及能够正确地执行下拉刷新
            self.pullupRefreshFlag = false
            
            if error != nil {
            
                print(error)
                
                return
            }
            
            let count = statusList?.count ?? 0
            
            // 判断是否是下拉刷新
            if since_id > 0 {
                
                self.showPulldownTip(count)
            
                // 拼接一下，将刷新出来的新数据拼接到之前的数据之前
                self.statuses = statusList! + self.statuses!
            }
                
            // 判断是否有数据，没有数据则直接返回
            if count == 0 {
                
                return
            }
                
            // 判断是否是上拉刷新，进行拼接
            else if max_id > 0 {
            
                self.statuses! += statusList!
                
            }
                
            else {
            
                self.statuses = statusList
            }
        }
    }
    
    // MARK: - 下拉提示方法
    private func showPulldownTip(count : Int) {
        
        // 解决提示条位置的错位的bug ：判断动画是否在执行中（块动画中，修改frame就是修改position）
        if pulldownTip.layer.animationForKey("position") != nil {
        
            print("动画正在执行中...")
            
            return
        }
    
        pulldownTip.text = (count == 0) ? "暂时没有新的微博哦~~" : "刷新到\(count)条微博~~"
        
        // 设置控件原始位置
        // 这里如果连续拖拽，会从没有完成的动画的目标位置开始下一次动画，造成提示条位置的错位
        let rect = pulldownTip.frame
        
        // 设置动画（UIView的动画是对核心动画的封装，添加到控件的layout上）
        UIView.animateWithDuration(2.0, animations: { () -> Void in
            
            // 自动反转动画，回到原来的位置
            UIView.setAnimationRepeatAutoreverses(true)
            
            self.pulldownTip.frame = CGRectOffset(rect, 0, 3 * rect.height)
            
            }) { (_) -> Void in
                
                // 让控件回到初始位置
                self.pulldownTip.frame = rect
        }
    }
    
    
    // MARK: - 实现数据源方法
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return statuses?.count ?? 0
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        
        // 创建cell
        // 获取数据
        let status = statuses![indexPath.row]
        
        let cell = tableView.dequeueReusableCellWithIdentifier(StatusCellID.cellID(status), forIndexPath: indexPath) as! StatusCell
        
        // 定义cell的代理
        cell.statusCellDelegate = self
        
        // 判断是否是最后一条数据，如果是，做刷新操作
        if indexPath.row == statuses!.count - 1 {
            
            // 修改上拉标记
            self.pullupRefreshFlag = true
            
            // 做刷新操作
            loadData()
        }
        
        cell.status = statuses![indexPath.row]
        
        return cell
    }
    
    // MARK: - 单元格选中了 http 超链接文字
    func statusCellDidSelectedLinkText(text: String) {
        
        print("链接文字\(text)")
        
        // 加载、跳转界面
        // 确定url是存在的
        guard let url = NSURL(string: text) else {
        
            print("URL不存在...")
            
            return
        }
        
        // 设置要弹出的控制器
        let vc = HomeWebViewContr()
        
        vc.url = url
        
        // 隐藏toolbar
        vc.hidesBottomBarWhenPushed = true
        
        // 弹出控制器(PUSH)
        navigationController?.pushViewController(vc, animated: true)
        
    }
    
    // MARK: -  返回行高
    /**   行高缓存
    1. NSCache - 内存缓存，iOS 8.0 有 bug，千万不要 removeAll，一旦 removeAll 之后，再也没法使
    SDWebImage 存在什么问题
    1> 接收到内存警告后，内存缓存实效
    2> 加载 GIF 的时候，内存会狂飙！
    2. 自定义行高`缓存字典`
    3. 直接利用微博的`模型` - 行高数据只是一个小数，并不会有太大的内存消耗！
    不需要在控制器中，额外定义属性！
    */
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        
        // 获取模型数据
        let status = statuses![indexPath.row]
        
        // 判断模型中是否返回了行高
        if let h = status.rowHeight {
        
            return h
        }
        
        // 获取cell
        let cell = tableView.dequeueReusableCellWithIdentifier(StatusCellID.cellID(status)) as? StatusCell
        
        // 记录并返回计算的行高
        status.rowHeight = cell!.rowheight(status)
        
        return cell!.rowheight(status)
        
    }
    
    // MARK: - 懒加载控件
    // 定义标签
    private lazy var pulldownTip : UILabel = {
        
        let h : CGFloat = 44
        
        let label = UILabel(frame: CGRect(x: 0, y: -2 * h, width: self.view.bounds.width, height: h))
        
        label.backgroundColor = UIColor.orangeColor()
        
        label.textColor = UIColor.whiteColor()
        
        label.textAlignment = NSTextAlignment.Center
        
        // 添加
        self.navigationController?.navigationBar.insertSubview(label, atIndex: 0)

        
        return label
        
    }()
    
    // 添加一个UIImageView视图（转场过程中的图像视图，替代cell进行变大动画）
    private lazy var presentIconView : UIImageView = {
        
        let imgView = UIImageView()
        
        // 设置图片样式
        imgView.contentMode = UIViewContentMode.ScaleAspectFill
        
        // 减去边界
        imgView.clipsToBounds = true
        
        return imgView
        
        }()
    
    // 是否是Modal展现的标记
    private var isPresent = false
    
    // 转场中选中的collectionView，通过它可以计算cell的起始位置以及目标位置
    private var pictView : StatusPictureView?
    
    // 记录选中的cell的indexPath
    private var presentIndex : NSIndexPath?

}

// MARK: - 遵守自定义转场协议（这两个方法返回的都是协议）
/// 注意 ：使用转场动画的时候，需要手动设置控件的位置以及大小，不要使用自动布局，否则会出现界面闪烁等bug
extension HomeTabContr : UIViewControllerTransitioningDelegate {
    
    // 展现：返回提供转场动画的遵守 `UIViewControllerAnimatedTransitioning` 协议的对象
    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        
        isPresent = true
        
        return self
    }
    
    // 解除：返回提供解除转场的对象，不写会使用系统默认的
    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        
        isPresent = false
        
        return self
    }
    
}

// MARK: - 自定义专场动画
extension HomeTabContr : UIViewControllerAnimatedTransitioning {

    // 返回转场动画时长
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
        
        return 1.0
    }
    
    // 自定义转场动画 -- 只要实现了这个方法，就需要自己写动画方法
    /**
    transitionContext : 提供了转场动画需要的元素
    completeTransition(true) 动画结束后必须调用的方法
    containerView() 容器视图
    viewForKey      获取到转场的视图
    */
    func animateTransition(transitionContext: UIViewControllerContextTransitioning)  {
        
//        // 测试代码
//        let fromVc = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) // 原始界面
//        let toVc = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)     // 目标界面
//        print(fromVc)
//        print(toVc)
        
        // Modal 展现
        if isPresent {
            
            // 展现动画（toView ： 目标控制器）
            let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
            
            // 将动画的图像视图添加到容器视图
            transitionContext.containerView()?.addSubview(presentIconView)
            
            // 起始位置以及目标位置
            let startRect = self.pictView!.cellScreenFrame(presentIndex!)
            
            let endRect = self.pictView!.cellFullScreenFrame(presentIndex!)
            
            // 指定动画图像视图的起始位置
            presentIconView.frame = startRect
            
            // 动画
            UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () -> Void in
                
                // 指定动画图像的目标位置
                self.presentIconView.frame = endRect
                
                }) { (_) -> Void in
                    
                    // 动画结束之后将动画图片视图移除，添加目标控制器
                    self.presentIconView.removeFromSuperview()
                    
                    transitionContext.containerView()?.addSubview(toView)
                    
                    // 如果没有执行这个方法，系统会一直等待，无法执行后续的交互
                    transitionContext.completeTransition(true)
            }
            
        } else {
            
            // 原始控制器
            let fromVc = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as! PhotoBrowserViewContr
            
            // 从控制器中获取当前显示图片的索引
            let indexPath = fromVc.currenImgIndex()
            
            // 获取PictureViewCell中collection cell对应的位置
            let rect = self.pictView!.cellScreenFrame(indexPath)
        
            // 目标视图
            let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
            
            // 获取当前显示的图片视图
            let iv = fromVc.currenImgView()
            
            // 设置iv的位置(解决位置不对的bug)
            iv.center = fromView.center
            
            // 累加父视图的形变(解决缩放之后会先变大再变回原来的位置的bug)
            iv.transform = CGAffineTransformScale(iv.transform, fromView.transform.a, fromView.transform.a)
            
            // 将当前显示的图片视图添加到容器视图中
            transitionContext.containerView()?.addSubview(iv)
            
            // 将目标视图从容器视图中移除
            fromView.removeFromSuperview()
            
            UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () -> Void in
                
                // 修改frame值
                iv.frame = rect
                
                }, completion: { (_) -> Void in
                    
                    // 移除
                    iv.removeFromSuperview()
                    
                    // 如果没有执行这个方法，系统会一直等待，无法执行后续的交互
                    transitionContext.completeTransition(true)
            })
        }
        
    }
    
}

